<?php

/**
 * @Author: Wang chunsheng  email:2192138785@qq.com
 * @Date:   2023-05-06 14:31:02
 * @Last Modified by:   Wang chunsheng  email:2192138785@qq.com
 * @Last Modified time: 2023-06-08 10:08:42
 */

namespace Common\Services\Sys;

use Common\BaseService;
use Common\Helpers\DebugHelper;
use Common\Helpers\StringHelper;
use Common\Models\Enums\NamePrefixEnums;
use Common\Models\sys\SysDevice;
use Common\Models\sys\SysDeviceCate;
use Hyperf\Constants\Exception\ConstantsException;
use Hyperf\Database\Model\Builder;
use Hyperf\Database\Model\Model;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Stringable\Str;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\SimpleCache\CacheInterface;
use Psr\SimpleCache\InvalidArgumentException;

class DeviceService extends BaseService
{
    /**
     * @Inject
     * @var CacheInterface
     */
    #[Inject]
    protected CacheInterface $cache;

    public static function addCate(string $title, int $cate_pid = 0, string $thumb = ''): bool
    {
        $SysDeviceCate = new SysDeviceCate();
        return $SysDeviceCate->addInfo([
            'title' => $title,
            'cate_pid' => $cate_pid,
            'thumb' => $thumb,
        ]);
    }

    public static function detailDevice($device_type, $building_remark, $room_remark, $floor_remark = 0, $unit_remark = 0): object|null
    {
        $SysDevice = new SysDevice();
        $where['type'] = $device_type;
        $where['building_remark'] = (int) $building_remark;
        $where['room_remark'] = (int) $room_remark;
        if ($floor_remark) {
            $where['floor_remark'] = $floor_remark;
        }
        if ($unit_remark) {
            $where['unit_remark'] = $unit_remark;
        }
        return $SysDevice->query()->where($where)->first();
    }

    public static function getMacById($id)
    {
        $SysDevice = new SysDevice();
        return $SysDevice->query()->where(['id' => $id])->value('device_mac');
    }

    public static function getInfoByRoom(int $device_type = 0,int $hotel_id= 0, int $room_id = 0, int $tier_id = 0, $column = ['*']): Model|SysDevice|Builder|null
    {
        $SysDevice = new SysDevice();
        return $SysDevice->query()->where([
            'type' => $device_type,
            'building_remark' => $hotel_id,
            'room_remark' => $room_id,
            'floor_remark' => $tier_id,
        ])->first($column);
    }

    /**
     */
    public static function getInfoByMac($mac, $column = ['*']): object|null
    {
        $SysDevice = new SysDevice();
        return $SysDevice->query()->where(['device_mac' => $mac])->first($column);
    }

    public static function listCate($page, $pageSize, int $cate_pid = 0): array
    {
        $SysDeviceCate = new SysDeviceCate();
        $where = [];
        if ($cate_pid) {
            $where['cate_pid'] = $cate_pid;
        }
        return $SysDeviceCate->getAll($page, $pageSize, $where);
    }

    public static function editCate(int $id, string $title, int $cate_pid = 0, string $thumb = ''): bool
    {
        $SysDeviceCate = new SysDeviceCate();
        return $SysDeviceCate->updateInfo([
            'title' => $title,
            'cate_pid' => $cate_pid,
            'thumb' => $thumb,
        ], [
            'id' => $id,
        ]);
    }

    public static function deleteCate(int $id)
    {
        $SysDeviceCate = new SysDeviceCate();
        return $SysDeviceCate->delInfo(['id' => $id]);
    }

    /**
     * @throws NotFoundExceptionInterface
     * @throws ConstantsException
     */
    public static function searchDevice($project_id, $devicve_type, $name, string $device_mac): array
    {
        $SysDevice = new SysDevice();
        $device_mac = str_replace(':', '', $device_mac);
        DebugHelper::consoleWrite('mac地址处理后用于查询', [$device_mac]);
//        status:0 =>出厂状态
        $devInfo = $SysDevice->query()->where(['device_mac' => $device_mac, 'project_id' => $project_id, 'type' => $devicve_type, 'status' => 0])->first(['type', 'id']);
        DebugHelper::consoleWrite('mac地址处理后用于查询-结果', [$devInfo]);

        if (empty($devInfo)){
            $names = NamePrefixEnums::getNames();
            DebugHelper::consoleWrite('设备名称规则匹配-列表', [$names]);

            foreach ($names as $v) {
                DebugHelper::consoleWrite('设备名称规则匹配', [$v,$name]);

                if (str_starts_with($name,$v)){
                    DebugHelper::consoleWrite('设备名称规则匹配成功', [$v,$name]);

                    $device_type = NamePrefixEnums::getVal($v);
                    DebugHelper::consoleWrite('设备名称规则匹配设备类型', [$v,$name,$device_type]);

                    $server_name = '';
                   self::initDevice($device_mac, $server_name, $device_type, $project_id);
                }
            }
            $devInfo = $SysDevice->query()->where(['device_mac' => $device_mac, 'project_id' => $project_id, 'type' => $devicve_type, 'status' => 0])->first(['type', 'id']);
        }
        return $devInfo ? $devInfo->toArray() : [];
    }

    /**
     * 根据硬件上报数据自动入库全局设备
     * @param string $device_mac
     * @param string $server_name
     * @param $device_type
     * @param int $project_id
     * @return int
     * @date 2023-05-22
     * @example
     * @author Wang Chunsheng
     * @since
     */
    public static function initDevice(string $device_mac, string $server_name, $device_type, int $project_id = 0): int
    {
        $SysDevice = new SysDevice();
        $device_id = $SysDevice->query()->where(['device_mac' => $device_mac])->value('id');
        if (!$device_id && $device_mac) {
            $device_sn = StringHelper::random(20);
            $device_id = $SysDevice->addInfo([
                'device_mac' => strtoupper($device_mac),
                'server_name' => $server_name,
                'device_type' => $device_type,
                'type' => $device_type,
                'project_id' => $project_id,
                'device_sn' => strtoupper($device_sn),
            ]);
        }
        return $device_id;
    }


    public static function bingDevice($title, $project_id, int $id, $building_remark, $floor_remark, $unit_remark, $room_remark): bool
    {
        $SysDevice = new SysDevice();
        return $SysDevice->updateInfo([
            'title' => $title,
            'project_id' => $project_id,
            'building_remark' => (int)$building_remark,
            'floor_remark' => (int)$floor_remark,
            'unit_remark' => (int)$unit_remark,
            'room_remark' => (int)$room_remark
        ], [
            'id' => $id,
        ]);
    }


    public static function removeDevice($member_id, $project_id, int $id): bool
    {
        $SysDevice = new SysDevice();
        return $SysDevice->updateInfo([
            'member_id' => $member_id,
            'building_remark' => 0,
            'floor_remark' => 0,
            'unit_remark' => 0,
            'room_remark' => 0
        ], [
            'id' => $id,
            'project_id' => $project_id
        ]);
    }

    /**
     * @param int $member_id
     * @param int $project_id
     * @param int $id
     * @param int $building_remark
     * @param int $floor_remark
     * @param int $room_remark
     * @param int $unit_remark
     * @return int|mixed
     */
    public static function delDevice(int $member_id, int $project_id, int $id = 0, int $building_remark = 0, int $floor_remark = 0, int $room_remark = 0, int $unit_remark = 0)
    {
        $SysDevice = new SysDevice();
        $where = [
            'member_id' => $member_id,
            'project_id' => $project_id,
        ];

        if ($building_remark) {
            $where['building_remark'] = $building_remark;
        }
        if ($floor_remark) {
            $where['floor_remark'] = $floor_remark;
        }
        if ($unit_remark) {
            $where['unit_remark'] = $room_remark;
        }
        if ($room_remark) {
            $where['room_remark'] = $unit_remark;
        }
        if ($id) {
            $where['id'] = $id;
        }

        return $SysDevice->delInfo($where);
    }


    /**
     * 手动入库设备信息
     * @param string $title
     * @param string $thumb
     * @param int $cate_pid
     * @param int $cate_id
     * @param string $desc
     * @param string $model_name
     * @param string $device_sn
     * @return array
     * @date 2023-05-22
     * @example
     * @author Wang Chunsheng
     * @since
     */
    public static function addDevice(string $title, string $thumb, int $cate_pid, int $cate_id, string $desc, string $model_name, string $device_sn): array|bool|int
    {
        $device_sn = Str::random(20);

        $SysDevice = new SysDevice();
        return $SysDevice->addInfo([
            'title' => $title,
            'thumb' => $thumb,
            'cate_pid' => $cate_pid,
            'cate_id' => $cate_id,
            'desc' => $desc,
            'model_name' => $model_name,
            'device_sn' => strtoupper($device_sn),
        ]);
    }

    public static function listDevice($page, $pageSize, int $cate_pid = 0): array
    {
        $SysDevice = new SysDevice();
        $where = [];
        if ($cate_pid) {
            $where['cate_pid'] = $cate_pid;
        }
        return $SysDevice->getAll($page, $pageSize, $where);
    }

    public static function editDevice(int $id, string $title, int $cate_pid = 0, int $cate_id = 0, string $desc = '', string $model_name = '', string $device_sn = ''): bool
    {
        $SysDevice = new SysDevice();
        $have = $SysDevice::query()->where(['id' => $id])->first();
        if (!$have) {
            return ResultHelper::json(400, '设备不存在');
        }
        $data = [];
        $data['title'] = $title;

        if ($cate_pid) {
            $data['cate_pid'] = $cate_pid;
        }
        if ($cate_id) {
            $data['cate_id'] = $cate_id;
        }
        if ($desc) {
            $data['desc'] = $desc;
        }
        if ($model_name) {
            $data['model_name'] = $model_name;
        }
        if ($device_sn) {
            $data['device_sn'] = $device_sn;
        }
        return $SysDevice->updateInfo($data, [
            'id' => $id,
        ]);
    }


    public static function deleteDevice(int $id)
    {
        $SysDevice = new SysDevice();
        return $SysDevice->delInfo(['id' => $id]);
    }
}
